package com.yonyou.iuap.ipaas.connector.sdwcoatencent.internal.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yonyou.iuap.ipaas.cache.core.CacheService;
import com.yonyou.iuap.ipaas.connector.sdk.exception.BusinessModuleException;
import com.yonyou.iuap.ipaas.connector.sdk.exception.CommonErrorTypeDefinition;
import com.yonyou.iuap.ipaas.connector.sdwcoatencent.api.model.core.constant.ApiConstants;
import com.yonyou.iuap.ipaas.connector.sdwcoatencent.api.model.common.Token;
import com.yonyou.iuap.ipaas.connector.sdwcoatencent.internal.SdwcoatencentConnection;
import com.yonyou.iuap.ipaas.connector.sdwcoatencent.internal.exception.ExecuteException;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;

/**
 * @author HuangWb
 * @description 企微API
 * @since 2024/8/14 9:51
 */
public class ApiUtil {
	
	public static final CacheService cacheService = CacheService.getCacheService();
	
	
	/**
	 * 企微 Api 统一访问入口
	 */
	public static <T> JSONObject doPostForm(String url, T postBody,  Integer timeout) {
		String responseBody = HttpRequest.post(url).body(JSONUtil.toJsonStr(postBody)).timeout(timeout).execute().body();
		checkResult(url, responseBody);
		return JSONUtil.parseObj(responseBody);
	}
	
	/**
	 * 企微 Api 统一访问入口
	 */
	public static <T> JSONObject doGetForm(String url, T postBody, Integer timeout) {
		String responseBody = HttpRequest.get(url).timeout(timeout).execute().body();
		checkResult(url, responseBody);
		return JSONUtil.parseObj(responseBody);
	}
	
	private static void checkResult(String url, String result) {
		if (!JSONUtil.isTypeJSON(result))
			throw BusinessModuleException.simpleException("999", url + " invoke exception:" + result, CommonErrorTypeDefinition.SERVER_RESPONSE_ERROR);
		if (JSONUtil.isTypeJSONObject(result)) {
			JSONObject resultJsonObject = JSONUtil.parseObj(result);
			if (resultJsonObject.containsKey("errcode") && resultJsonObject.containsKey("errmsg"))
				throw BusinessModuleException.simpleException("999", url + " invoke exception:" + resultJsonObject.getStr("errmsg"), CommonErrorTypeDefinition.SERVER_RESPONSE_ERROR);
		}
	}
	
	public static String getAccessToken(SdwcoatencentConnection connection) {
		String cacheKey = "token:" + connection.getCorpid();
		Object cacheValue = cacheService.get(cacheKey);
		if (cacheValue != null) {
			// 判断初始令牌的过期时间是否超过1小时58分，开发者请在访问令牌过期之前（授权后2小时内），通过更新令牌接口主动请求开放平台，获取新的访问令牌。
			String[] cacheValueArr = Convert.toStr(cacheValue).split("@");
			String accessToken = cacheValueArr[0];
			// 当前时间戳-缓存刚存进去的时间戳 为 访问令牌已消耗的过期时间
			long startTimeMillis = System.currentTimeMillis() - Long.parseLong(cacheValueArr[1]);
			if (startTimeMillis >= ApiConstants.ACCESS_TOKEN_REFRESH_MILLISECOND && startTimeMillis < ApiConstants.ACCESS_TOKEN_EXPIRE_SECOND * 1000) {
				// 执行刷新token接口
				String url = String.format(connection.getHost() + ApiConstants.APP_ACCESS_TOKEN);
				HashMap<String, Object> getTokenParam = new HashMap<>();
				getTokenParam.put("corpid", connection.getCorpid());
				getTokenParam.put("corpsecret", connection.getAppCorpsecret());
				String responseBody = HttpUtil.get(url, getTokenParam, connection.getHttpTimeOut());
				Token token = JSON.readValue(responseBody, Token.class);
				accessToken = token.getAccess_token();
				if (StringUtils.isEmpty(accessToken)) {
					throw ExecuteException.serverResponseError("企微请求出错：accessToken初始化获取报错");
				}
				long expiresIn = token.getExpires_in();
				// 存入缓存内容
				cacheService.put(cacheKey, accessToken + "@" + System.currentTimeMillis(), expiresIn * 1000);
			}
			return accessToken;
		}
		// 获取accessToken
		String url = String.format(connection.getHost() + ApiConstants.APP_ACCESS_TOKEN);
		HashMap<String, Object> getTokenParam = new HashMap<>();
		getTokenParam.put("corpid", connection.getCorpid());
		getTokenParam.put("corpsecret", connection.getAppCorpsecret());
		String responseBody = HttpUtil.get(url, getTokenParam, connection.getHttpTimeOut());
		Token token = JSON.readValue(responseBody, Token.class);
		String accessToken = token.getAccess_token();
		if (StringUtils.isEmpty(accessToken)) {
			throw ExecuteException.serverResponseError("企微请求出错：accessToken初始化获取报错");
		}
		long expiresIn = token.getExpires_in();
		// 存入缓存内容
		cacheService.put(cacheKey, accessToken + "@" + System.currentTimeMillis(), expiresIn * 1000);
		return accessToken;
	}
	
	public static String getAccessToken(String corpid,String host,String appCorpsecret,int httpTimeOut) {
		String cacheKey = "token:" + corpid;
		Object cacheValue = cacheService.get(cacheKey);
		if (cacheValue != null) {
			// 判断初始令牌的过期时间是否超过1小时58分，开发者请在访问令牌过期之前（授权后2小时内），通过更新令牌接口主动请求开放平台，获取新的访问令牌。
			String[] cacheValueArr = Convert.toStr(cacheValue).split("@");
			String accessToken = cacheValueArr[0];
			// 当前时间戳-缓存刚存进去的时间戳 为 访问令牌已消耗的过期时间
			long startTimeMillis = System.currentTimeMillis() - Long.parseLong(cacheValueArr[1]);
			if (startTimeMillis >= ApiConstants.ACCESS_TOKEN_REFRESH_MILLISECOND && startTimeMillis < ApiConstants.ACCESS_TOKEN_EXPIRE_SECOND * 1000) {
				// 执行刷新token接口
				String url = String.format(host + ApiConstants.APP_ACCESS_TOKEN);
				HashMap<String, Object> getTokenParam = new HashMap<>();
				getTokenParam.put("corpid", corpid);
				getTokenParam.put("corpsecret", appCorpsecret);
				String responseBody = HttpUtil.get(url, getTokenParam, httpTimeOut);
				Token token = JSON.readValue(responseBody, Token.class);
				accessToken = token.getAccess_token();
				if (StringUtils.isEmpty(accessToken)) {
					throw ExecuteException.serverResponseError("企微请求出错：accessToken初始化获取报错");
				}
				long expiresIn = token.getExpires_in();
				// 存入缓存内容
				cacheService.put(cacheKey, accessToken + "@" + System.currentTimeMillis(), expiresIn * 1000);
			}
			return accessToken;
		}
		// 获取accessToken
		String url = String.format(host + ApiConstants.APP_ACCESS_TOKEN);
		HashMap<String, Object> getTokenParam = new HashMap<>();
		getTokenParam.put("corpid", corpid);
		getTokenParam.put("corpsecret", appCorpsecret);
		String responseBody = HttpUtil.get(url, getTokenParam, httpTimeOut);
		Token token = JSON.readValue(responseBody, Token.class);
		String accessToken = token.getAccess_token();
		if (StringUtils.isEmpty(accessToken)) {
			throw ExecuteException.serverResponseError("企微请求出错：accessToken初始化获取报错");
		}
		long expiresIn = token.getExpires_in();
		// 存入缓存内容
		cacheService.put(cacheKey, accessToken + "@" + System.currentTimeMillis(), expiresIn * 1000);
		return accessToken;
	}
	
}
